require("utils")
require("tier2")
require("gems")
require("enchants")
require("eq") -- eq.lua
require("buffs") -- buffs.lua
require("races") -- races.lua

local FSR_RATIO = 0.8

local unit = {
	race = "NIGHTELF",
	class = "DRUID",
	level = 70,
	innate = {
		strength = 73,
		intellect = 120,
		agility = 75, 
		stamina = 82, 
		spirit = 132,
		skill_defense = 350,
		skill_weapon_feral = 350,
		armor = 0,
		maxhealth = 3614,
		maxmana = 2370,
		meleeattackpower = -20,
	},
	auras = {
		-- Talents
		{ type = "modifier", attribute = "spirit", value = 15 }, 
		{ type = "stat", attribute = "spellcrit", value = 3 },
		{ type = "stat", attribute = "manareg_fsr_p", value = 0.30 },
		-- Tree of Life form:
		{ type = "modifier", attribute = "healing", reference = "spirit", multiplier = 0.25 },
		-- Night Elf
		{ type = "stat", attribute = "dodge", value = 1 },
		-- Dire Bear form:
--~ 		{ type = "modifier", attribute = "base_armor", value = 400 },
--~ 		{ type = "modifier", attribute = "stamina", value = 25 },
--~ 		{ type = "stat", attribute = "meleeattackpower", value = 120 },
	},
}

local heal_eq = {
	head = {
		item = eq.head.za,
		socket1 = gems.purple.pure_pearl,
		socket2 = gems.orange.lum_noble_topaz,
		socket3 = gems.purple.pure_pearl,
		enchant = enchants.head.heal_hh,
	},
	neck = {
		item = eq.neck.nether,
	},
	shoulders = {
		item = eq.shoulders.za_badge,
		socket1 = gems.purple.pure_pearl,
		socket2 = gems.orange.lum_noble_topaz,
		enchant = enchants.shoulders.aldor_exalted,
	},
	back = {
		item = eq.back.prince,
	},
	chest = {
		item = eq.chest.morogrim,
		enchant = enchants.chest.spirit,
	},
	wrists = {
		item = eq.wrists.lurker,
		enchant = enchants.wrists.healing,
	},
	mainhand = {
		item = eq.mainhand.solarian,
		enchant = enchants.mainhand.spirit,
	},
	hands = {
		item = eq.hands.eye_trash,
		enchant = enchants.hands.healing,
	},
	waist = {
		item = eq.waist.void,
		socket1 = gems.purple.blessed_tanzanite,
		socket2 = gems.purple.soothing_amethist,
	},
	legs = {
		item = eq.legs.t5,
		socket1 = gems.purple.pure_pearl,
		enchant = enchants.legs.aldor_exalted,
	},
	feet = {
		item = eq.feet.leotheras,
		socket1 = gems.purple.pure_pearl,
		socket2 = gems.purple.pure_pearl,
		enchant = enchants.feet.spirit,
	},
	finger1 = {
		item = eq.finger.heroic_black_stalker,
	},
	finger2 = {
		item = eq.finger.karazhan_exalted,
	},
	trinket1 = {
		item = eq.trinket.bwl_rejuv,
	},
	trinket2 = {
		item = eq.trinket.kara_opera,
	},
}

local heal2_eq = utils.clone(heal_eq)

heal2_eq.finger1 = { -- Vashj 21.8
	item = eq.finger.vashj,
}

--~ heal2_eq.chest = { -- T5 16
--~ 	item = eq.chest.t5,
--~ 	socket1 = gems.purple.pure_pearl,
--~ 	socket2 = gems.purple.pure_pearl,
--~ 	socket3 = gems.purple.pure_pearl,
--~ 	enchant = enchants.chest.spirit,
--~ }

heal2_eq.hands = { -- T5 12.1
	item = eq.hands.t5,
	enchant = enchants.hands.healing,
}

heal2_eq.back = { -- Kael'Thas 11.4
	item = eq.back.kaelthas,
}

--~ heal2_eq.head = { -- T5  10.9 (overpriced) (5.9/meta)
--~ 	item = eq.head.t5,
--~ 	socket1 = gems.meta.healing,
--~ 	socket2 = gems.purple.pure_pearl,
--~ 	enchant = enchants.head.heal_hh,
--~ }

heal2_eq.shoulders = { -- T5 7.6
	item = eq.shoulders.t5,
	socket1 = gems.purple.pure_pearl,
	socket2 = gems.purple.pure_pearl,
	enchant = enchants.shoulders.aldor_exalted,
}

--~ heal2_eq.shoulders = { -- Vashj 0.5
--~ 	item = eq.shoulders.vashj,
--~ 	enchant = enchants.shoulders.aldor_exalted,
--~ }

--~ heal2_eq.mainhand = { -- 103.5
--~ 	item = eq.mainhand.kt_legendary,
--~ }
--~ heal2_eq.offhand = { 
--~ 	item = eq.offhand.moroes,
--~ 	item = eq.offhand.za_badge, -- 110.8
--~ }

--~ heal2_eq.mainhand = { -- -28
--~ 	item = eq.mainhand.malchezaar,
--~ 	enchant = enchants.mainhand.healing,
--~ }
--~ heal2_eq.offhand = { 
--~ 	item = eq.offhand.moroes,
--~ 	item = eq.offhand.za_badge, - 22.1
--~ }

--~ heal2_eq.mainhand.enchant = enchants.mainhand.healing -- -6.5

--~ heal2_eq.legs = { -- Solarian -7.9
--~ 	item = eq.legs.c_solarian,
--~ 	enchant = enchants.legs.aldor_exalted,
--~ }

local b = {
	buffs.mark_of_the_wild,
	buffs.fortitude,
	buffs.arcane_brilliance,
	buffs.spirit,
	buffs.well_fed_healspirit,
	buffs.blessing_kings,
	buffs.wisdom_elixir,

--~ 	buffs.winterveil_spirit,
}

local function main ()
	local unit_2 = utils.clone(unit)

	utils.InsertAuras(unit, utils.GetEquipmentAuras(heal_eq))
	utils.InsertAuras(unit, b)

	utils.InsertAuras(unit_2, utils.GetEquipmentAuras(heal2_eq))
	utils.InsertAuras(unit_2, b)

	tier2.CALCULATORS.innervate = function (unit, tier1)
		local manareg = tier2.get(unit, tier1, "manareg")
		return manareg * (1 + 400 / 100) * (2 / 5) * (18 / 2)
	end
	tier1.EMPTY.innervate = 0
	tier1.EMPTY.mreg = 0

	tier2.CALCULATORS.mreg = function (unit, t1)
		return (tier2.get(unit, t1, "manareg_fsr") * FSR_RATIO + tier2.get(unit, t1, "manareg") * (1 - FSR_RATIO)) / 5
	end
	
	tier2.CALCULATORS.lifebloom_healing_power = function (unit, t1)
		local healing = tier2.get(unit, t1, "healing")
		local mana = tier2.get(unit, t1, "maxmana") + tier2.get(unit, t1, "innervate")
		local manareg = (tier2.get(unit, t1, "manareg_fsr") * FSR_RATIO + tier2.get(unit, t1, "manareg") * (1 - FSR_RATIO)) / 5
		
		local crit = tier2.get(unit, t1, "spellcrit") / 100
		crit = 1 + (crit / 100)
		local lifebloom_healing = ((healing * 0.46 + 273) + (healing * 0.46 + 600)) * crit
		local lifebloom_time = 1.5
		local lifebloom_cost = 220 * 0.8 - manareg * lifebloom_time
		
		local lifebloom_casts = mana / lifebloom_cost
		local lifebloom_heal = lifebloom_healing * lifebloom_casts
		
		return lifebloom_heal
	end
	tier1.EMPTY.lifebloom_healing_power = 0


	local v1, v2 = tier2.calc(unit), tier2.calc(unit_2)

	for s, v in pairs(v1) do
		if v ~= 0 or v2[s] ~= 0 then
			local diff = v2[s] - v
			if diff > 0 then
				diff = ("+%.1f"):format(diff)
			elseif diff < 0 then
				diff = ("-%.1f"):format(-diff)
			else
				diff = nil -- ""
			end
--~ 			if diff then print(s, ("%.2f"):format(v1[s]), diff) end
		end
	end

	local a, b = v2.lifebloom_healing_power - v1.lifebloom_healing_power, v2.spirit - v1.spirit
--~ 	print(string.format("%.1f", a * 0.001 + b * 0.1), v2.spirit, v2.manareg, v2.manareg_fsr, v2.innervate)
	print( 
		string.format("Esprit: %d", math.floor(v2.spirit + .5)), 
		string.format("Valeur: %.1f", a * 0.001 + b * 0.1),  
		string.format("DSpi  : %.1f", b),
		string.format("DHeal : %.1f", v2.healing - v1.healing),
		string.format("Dmreg : %.1f", v2.mreg - v1.mreg)
	)
end

local warrior = {
	race = "NIGHTELF",
	class = "WARRIOR",
	level = 70,
	can_parry = true,
	can_block = true,
	innate = {
		strength = 144,
		agility = 96,
		stamina = 132,
		intellect = 33,
		spirit = 51,
		skill_defense = 350,
		maxhealth = 4440,
		parry = 5,
		block = 5,
	},
	auras = {
		{ type = "modifier", attribute = "spirit", value = 10 }, 
		{ type = "stat", attribute = "parry", value = 5 },
		{ type = "stat", attribute = "skill_defense", value = 20 },
		{ type = "stat", attribute = "block", value = 5 },
		{ type = "modifier", attribute = "base_armor", value = 10 }, 
		{ type = "stat", attribute = "expertise", value = 6 },
		{ type = "modifier", attribute = "blockvalue", value = 30 },
		{ type = "modifier", attribute = "stamina", value = 5 }, 
		{ type = "modifier", attribute = "strength", value = 10 }, 
	},
}

local w_eq = {
	head = {
		item = eq.head.w_t4,
		enchant = enchants.head.def_cot,
		socket1 = gems.meta.def,
		socket2 = gems.green.def_stam,
	},
	neck = {
		item = eq.neck.w_maiden,
	},
	shoulders = {
		item = eq.shoulders.w_d3,
		socket1 = gems.green.def_stam,
		socket2 = gems.blue.stam12,
		enchant = enchants.shoulders.def_scryer_honored,
	},
	back = {
		item = eq.back.w_badge,
	},
	chest = {
		item = eq.chest.w_sepethrea,
		enchant = enchants.chest.stam10,
	},
	wrists = {
		item = eq.wrists.w_h_kalithresh,
		enchant = enchants.wrists.stam12,
	},
	mainhand = {
		item = eq.mainhand.kargath,
	},
	offhand = {
		item = eq.offhand.w_shield,
	},
	ranged = {
		item = eq.ranged.w_bow,
	},
	hands = {
		item = eq.hands.w_d3,
		socket1 = gems.red.agility,
		socket2 = gems.green.def_stam,
		enchant = enchants.hands.stam10,
	},
	waist = {
		item = eq.waist.w_badge,
		socket1 = gems.blue.stam12,
		socket2 = gems.yellow.hit8,
	},
	legs = {
		item = eq.legs.w_kargath,
		socket1 = gems.orange.dodge_hit,
		socket2 = gems.yellow.def4,
		socket3 = gems.purple.str_stam,
		enchant = enchants.legs.stam_agi,
	},
	feet = {
		item = eq.feet.w_remparts,
		socket1 = gems.red.str4,
		socket2 = gems.blue.stam6,
		enchant = enchants.feet.stam10,
	},
	finger1 = {
		item = eq.finger.w_kara_blue,
	},
	finger2 = {
		item = eq.finger.w_h_mana,
	},
	trinket1 = {
		item = eq.trinket.slab_def,
	},
	trinket2 = {
		item = eq.trinket.w_dm,
	},
}

local b = {
	buffs.mark_of_the_wild,
	buffs.fortitude,
	buffs.blood_pact,
--~ 	buffs.arcane_brilliance,
--~ 	buffs.spirit,
	buffs.well_fed_stamspirit,
--~ 	buffs.winterveil_spirit,
	buffs.blessing_kings,
--~ 	buffs.wisdom_elixir,
}

utils.InsertAuras(warrior, utils.GetEquipmentAuras(w_eq))
utils.InsertAuras(warrior, b)

function main_w()

	local t1 = tier1.calc(warrior)

--~ 	print("----")
--~ 	for k, v in pairs(t1.ratings) do
--~ 		print(k, v, ("%.2f"):format(utils.GetRatingBonus(k, v, 70)))
--~ 	end

	local v = tier2.calc(warrior)

	print("----")
	for s, v in pairs(v) do
		if v ~= 0 then print(s, v) end
	end

	print("----")
	local avoidance = (math.floor(v.skill_defense) - 350) * 0.04 -- miss
	avoidance = 5 + (avoidance < 0 and 0 or avoidance)
	avoidance = avoidance + v.dodge + v.parry
	print("avoidance", avoidance)

	local armor_mitigation = utils.GetArmorMitigation(v.armor, 70)
	print("armor", armor_mitigation * 100)
	local mitigation = avoidance + (100 - avoidance) * armor_mitigation
	print("mitigation", mitigation)

	local idps = 1000 * (1 - mitigation / 100)
	local survival = v.maxhealth / idps
	print("time to live", survival)

	local avoidance = (math.floor(530) - 350) * 0.04 -- miss
	avoidance = 5 + (avoidance < 0 and 0 or avoidance)
	avoidance = avoidance + 25.36 + 17.2
	print("avoidance", avoidance)

	local armor_mitigation = utils.GetArmorMitigation(16774, 70)
	print("armor", armor_mitigation * 100)
	local mitigation = avoidance + (100 - avoidance) * armor_mitigation
	print("mitigation", mitigation)

	local idps = 1000 * (1 - mitigation / 100)
	local survival = 16000 / idps
	print("time to live", survival)

	print(utils.GetRatingBonus("skill_defense", 379, 70))
end

main()
